<template>
	<!-- 单张图片上传 -->
	<div class="component-upload-image" :style="widthAndHeight">
		<!-- :http-request="upload" -->
		<el-upload action="" list-type="picture-card" :on-error="handleUploadError" v-loading="loading" class="img-uploader"
			:show-file-list="false" :auto-upload="false" :on-change="handleChange" :disabled="disabled"
			style="display: inline-block; vertical-align: top" :element-loading-text="isZip ? '正在进行图片压缩' : '上传中'">
			<el-image v-if="!modelValue" :src="modelValue">
				<div slot="error" class="image-slot">
					<i v-if="!disabled" class="el-icon-plus" />
					<b v-else>暂无</b>
				</div>
			</el-image>
			<div v-else class="image">
				<el-image :src="modelValue" class="pbImage" fit="fill" />
				<div class="mask" @click.stop="imgLook">
					<div class="actions">
						<span style="cursor: pointer">
							<i style="color: #fff; font-size: 20px" class="el-icon-zoom-in" />
						</span>
						<span v-if="!disabled" @click.stop="removeImage" style="cursor: pointer"
							:style="{ 'margin-left': width > 80 ? '15px' : '5px' }">
							<i style="color: #fff; font-size: 20px" class="el-icon-delete" />
						</span>
					</div>
				</div>
			</div>
		</el-upload>
		<el-input v-if="showInput" v-model.trim="modelValue" placeholder="请输入图片链接" clearable></el-input>
		<div class="el-upload__tip" style="margin-top: 0" v-if="showTip">
			<template v-if="widthPx && heightPx && ratio">
				宽
				<b style="color: #f56c6c">{{ widthPx }}</b> 像素，高
				<b style="color: #f56c6c">{{ heightPx }}</b> 像素，建议宽高比为
				<b style="color: #f56c6c">{{ ratio }}</b>
			</template>
		</div>
		<!-- 图片描述 -->
		<div class="el-upload__tip" style="width: 100px; display: flex; justify-content: center" v-if="Description">
			<template>
				<b style="text-align: center">{{ Description }}</b>
				<i v-if="requireItem" style="color: #ff0000">*</i>
			</template>
		</div>
		<!--  -->
		<el-dialog :visible.sync="dialogVisible" title="预览" class="dialog" append-to-body :lock-scroll="false"
			:width="dialogWidth" :close-on-click-modal="false" :close-on-press-escape="false" custom-class="preview-dialog"
			:modal="false" v-dialog-drag>
			<!-- <div style="width: 100%; height: 100%"> -->
			<div id="img_box" v-if="dialogVisible">
				<viewer v-if="preview" :images="viewers" ref="viewer" class="w-700px h-640px">
					<img class="w-640px h-640px hidden" v-for="src in viewers" :key="src" :src="src" alt="image" />
				</viewer>
				<img v-else style="width: 100%; height: 100%" :src="modelValue" />
			</div>
			<!-- </div> -->
		</el-dialog>
	</div>
</template>

<script>
import * as imageConversion from "image-conversion";
import uploadFile from "@/utils/upload";

export default {
	model: {
		prop: "modelValue",
		event: "update:modelValue",
	},
	props: {
		modelValue: { type: String, default: "" },
		isShowTip: { type: Boolean, default: true }, // 是否显示提示
		showInput: { type: Boolean, default: false }, // 是否显示链接输入框
		disabled: { type: Boolean, default: false }, // 是否禁用
		width: { type: [Number, String], default: 100 }, // 上传框的宽
		height: { type: [Number, String], default: 100 }, // 上传框的高
		widthPx: { type: [Number, String], default: "" }, // 建议图片宽像素值
		heightPx: { type: [Number, String], default: "" }, // 建议图片高像素值
		ratio: { type: String, default: "" }, // 建议图片宽高比
		fileType: {
			type: Array,
			default: () => ["png", "jpg", "jpeg"],
		}, // 文件类型, 例如['png', 'jpg', 'jpeg']
		Description: {
			type: String,
			default: null,
		},
		// 当前是否必须上传
		requireItem: {
			type: Boolean,
			default: false,
		},
		preview: {
			type: Boolean,
			default: false,
		},
		viewers: {
			type: Array,
			default: () => [],
		},
		dialogWidth: {
			type: String,
			default: null,
		},
	},
	computed: {
		showTip() {
			return this.isShowTip && this.heightPx && this.widthPx && this.ratio;
		},
		widthAndHeight() {
			return {
				"--height": this.height + "px",
				"--width": this.width + "px",
			};
		},
	},
	data() {
		return {
			loading: false,
			isZip: false,
			dialogVisible: false,
		};
	},
	methods: {
		upload(data) {
			let that = this;
			// console.log('data',data)
			this.loading = true;
			uploadFile(data, data.name)
				.then((res) => {
					console.log("res", res);
					that.$emit("imgUploadSuccess");
					that.$emit("update:modelValue", res.url);
					that.loading = false;
				})
				.catch((err) => {
					that.loading = false;
				});
		},
		removeImage() {
			this.$emit("imgUploadRemove", this.modelValue);
			this.$emit("update:modelValue", "");
		},
		// handleUploadSuccess(res) {
		//   this.$emit('update:modelValue', res.data.url)
		//   this.loading = false
		// },
		handleChange(file) {
			let filetemp = file.raw;
			if (filetemp) {
				// 校检文件类型
				if (this.fileType.length) {
					let fileExtension = "";
					if (filetemp.name.lastIndexOf(".") > -1) {
						fileExtension = filetemp.name.slice(
							filetemp.name.lastIndexOf(".") + 1,
						);
					}
					const isTypeOk = this.fileType.some((type) => {
						if (filetemp.type.indexOf(type) > -1) return true;
						if (fileExtension && fileExtension.indexOf(type) > -1) return true;
						return false;
					});
					if (!isTypeOk) {
						this.$message.error(
							`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`,
						);
						return false;
					}
				}
			}
			this.loading = true;
			return new Promise((resolve, reject) => {
				// console.log('压缩前', filetemp.size / 1024 / 1024)
				// 如果图片超过1.5m就压缩
				if (filetemp.size / 1024 / 1024 > 1.5) {
					this.isZip = true;
					imageConversion
						.compressAccurately(filetemp, {
							size: 750,
							scale: 0.5,
						})
						.then((res) => {
							let result = new File([res], filetemp.name, {
								type: res.type,
								lastModified: Date.now(),
							});
							// console.log('压缩', res.size / 1024 / 1024);
							this.isZip = false;
							// console.log('11111111111111', result)
							this.upload(result);
						});
				} else {
					// console.log('没压缩', filetemp.size / 1024 / 1024);
					this.isZip = false;
					// console.log('2222222222222222222', filetemp)
					this.upload(filetemp);
				}
			});
		},
		handleUploadError() {
			this.loading = false;
			this.$message({
				type: "error",
				message: "上传失败",
			});
		},
		imgLook() {
			this.dialogVisible = true;
			if (this.preview) {
				let arr = JSON.parse(JSON.stringify(this.viewers));
				let afterArr = arr.filter((item) => item !== "");
				let index = afterArr.findIndex((item) => item === this.modelValue);
				if (index > -1) {
					this.$nextTick(() => {
						console.log(this.$refs.viewer);
						this.$refs.viewer.$viewer.view(index);
					});
				}
			}
		},
	},
};
</script>

<style scoped lang="scss">
.image {
	position: relative;
	width: var(--width);
	height: var(--height);
	line-height: var(--height);

	.mask {
		background-color: rgba(0, 0, 0, 0);
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		cursor: default;
	}

	&:hover .mask {
		transition: all 0.3s;
		background-color: rgba(0, 0, 0, 0.5);
	}

	&:hover .actions {
		transition: all 0.3s;
		opacity: 1;
	}
}

.actions {
	width: var(--width);
	line-height: var(--height);
	opacity: 0;
}

.pbImage {
	width: var(--width);
	height: var(--height);
}

::v-deep .el-upload--picture-card {
	width: var(--width) !important;
	height: var(--height) !important;
	line-height: var(--height) !important;
	border-radius: 6px !important;
	overflow: hidden !important;
}

.image-slot {
	width: var(--width) !important;
	height: var(--height) !important;
	line-height: var(--height) !important;
}

::v-deep .el-image__inner {
	object-fit: cover !important;
}

.el-dialog__wrapper {
	pointer-events: none; //dialog外包裹的盒子区域设置鼠标不再操作当前层

	::v-deep .el-dialog {
		pointer-events: auto; //dialog真正区域设置鼠标操作当前层
	}
}

.dialog ::v-deep .el-dialog__body {
	padding: 0 !important;
}
</style>
